package cn.hl.hm.util.chinapay;


import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONException;
import net.sf.json.JSONObject;

import org.codehaus.jackson.map.ObjectMapper;

import com.chinapay.secss.SecssUtil;
import com.chinapay.util.Base64;
import com.chinapay.util.log.MonitorLogger;

/** 
 * 测试类  .
 * @author 
 * @serial  .
 * @since 2012-10-11 上午09:01:57 .
 */
public class UnionValidServlet extends HttpServlet {
	/**
	 * 
	 */
	private static final long serialVersionUID = -4754088252205918884L;
	
	/**
	 * 构造日志对象 .
	 */
	private static final MonitorLogger logger = MonitorLogger.getLogger(UnionValidServlet.class);
	
	/**
	 * GET请求.
	 * @param request .
	 * @param response .
	 * @throws IOException .
	 * @throws ServletException .
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request, response);
	}
	
	/**
	 * POST请求.
	 * @param request .
	 * @param response .
	 * @throws IOException .
	 * @throws ServletException .
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		
		Map<String, String> respmsgMap = new HashMap<String,String>();
		
		String merNo = request.getParameter("merNo");
		String instId = request.getParameter("instId");
		String busiType = request.getParameter("busiType");
		String orderDate = request.getParameter("orderDate");
		String orderId = request.getParameter("orderId");
		
		String usrSysId = request.getParameter("usrSysId");
		String email = request.getParameter("email");
		String mobile = request.getParameter("mobile");
		String bizType = request.getParameter("bizType");
		String channelMerId = request.getParameter("channelMerId");
		String channelMerName = request.getParameter("channelMerName");
		String channelMerKey = request.getParameter("channelMerKey");
		String save = request.getParameter("save");
		String dcType = request.getParameter("dcType");
		String cardNo = request.getParameter("cardNo");
		String certType = request.getParameter("certType");
		String certNo = request.getParameter("certNo");		
		String usrName = request.getParameter("usrName");
		String pin = request.getParameter("pin");
		String smFlag = request.getParameter("smFlag");
		String cardPhone = request.getParameter("cardPhone");
		String bgRetUrl = request.getParameter("bgRetUrl");
		String cardHolderIp = request.getParameter("cardHolderIp");
		
		String xmpy = request.getParameter("xmpy");
		String txnDate = request.getParameter("txnDate");
		String queryFlag = request.getParameter("queryFlag");
		String validType = request.getParameter("validType");
		String compareXp = request.getParameter("compareXp");
		String xp = request.getParameter("xp");
		String ip = request.getParameter("ip");
		String mchntCode = request.getParameter("mchntCode");
		String mchntCodeTp = request.getParameter("mchntCodeTp");
		String imei = request.getParameter("imei");
		String hardDiskSerialNum = request.getParameter("hardDiskSerialNum");
		String webAddr = request.getParameter("webAddr");
		String sessionId = request.getParameter("sessionId");
		
		String key = request.getParameter("key");
		String keyType = request.getParameter("keyType");
		String orderType = request.getParameter("orderType");
		String deviceOs = request.getParameter("deviceOs");
		String sdkMerNo = request.getParameter("sdkMerNo");
		String merType = request.getParameter("merType");
		String merResv = request.getParameter("merResv");
		
		//Base64后交易报文ObjectMapper
		String reqDataStr = null;
		
		// 初始化
		SecssUtil secssUtil = new SecssUtil();
		String fileKey = StringUtil.isNotEmpty(instId)?instId:merNo;
		logger.debug("配置文件路径:"+ PathUtil.getValue("security_"+fileKey+"_url"));
		secssUtil.init(PathUtil.getValue("security_"+fileKey+"_url"));
//		secssUtil.init();
		
		JSONObject reqDataJson = new JSONObject();
		try
		{
			if (StringUtil.isNotEmpty(merNo)) {
				reqDataJson.put("merNo", merNo);
		    }
		    reqDataJson.put("busiType", busiType);
		    if (StringUtil.isNotEmpty(instId)) {
		    	reqDataJson.put("instId", instId);
		    }
		    if (StringUtil.isNotEmpty(merResv)) {
		    	reqDataJson.put("merResv", merResv);
		    }
		    
		    if (!"2001".equals(busiType) || !"2003".equals(busiType)){
			    reqDataJson.put("orderDate", orderDate);
			    reqDataJson.put("orderId", orderId);
		    }
		if ("1001".equals(busiType) || 
			"1002".equals(busiType) || 
			"1003".equals(busiType) || 
			"1004".equals(busiType)) {
			if (StringUtil.isNotEmpty(usrSysId)) {
				reqDataJson.put("usrSysId", usrSysId);
			}
			if (StringUtil.isNotEmpty(email)) {
				reqDataJson.put("email", email);
			}
			if (StringUtil.isNotEmpty(mobile)) {
				reqDataJson.put("mobile", mobile);
			}
			if (StringUtil.isNotEmpty(bizType)) {
				reqDataJson.put("bizType", bizType);
			}
			if (StringUtil.isNotEmpty(channelMerId)) {
				reqDataJson.put("channelMerId", channelMerId);
			}
			if (StringUtil.isNotEmpty(channelMerName)) {
				reqDataJson.put("channelMerName", channelMerName);
			}
			if (StringUtil.isNotEmpty(channelMerKey)) {
				reqDataJson.put("channelMerKey", channelMerKey);
			}
			if (StringUtil.isNotEmpty(save)) {
				reqDataJson.put("save", save);
			}
			if (StringUtil.isNotEmpty(dcType)) {
				reqDataJson.put("dcType", dcType);
			}
			if (StringUtil.isNotEmpty(certType)) {
				reqDataJson.put("certType", certType);
			}
			if (StringUtil.isNotEmpty(usrName)) {
				reqDataJson.put("usrName", usrName);
			}
			if (StringUtil.isNotEmpty(smFlag)) {
				reqDataJson.put("smFlag", smFlag);
			}
//			if (StringUtil.isNotEmpty(bgRetUrl)) {
//				reqDataJson.put("bgRetUrl", bgRetUrl);
//			}
			if (StringUtil.isNotEmpty(cardHolderIp)) {
				reqDataJson.put("cardHolderIp", cardHolderIp);
			}
		}
		
		if(!busiType.startsWith("2")){
			if (StringUtil.isNotEmpty(bgRetUrl)) {
				reqDataJson.put("bgRetUrl", bgRetUrl);
			}
		}
		
		if ("1005".equals(busiType)) {
			if (StringUtil.isNotEmpty(xmpy)) {
				reqDataJson.put("xmpy", xmpy);
			}
		}
		
		if ("1006".equals(busiType)) {
			if (StringUtil.isNotEmpty(usrName)) {
				reqDataJson.put("usrName", usrName);
			}
		}
		
		if ("1007".equals(busiType)) {
			if (StringUtil.isNotEmpty(compareXp)) {
				reqDataJson.put("compareXp", compareXp);
			}
			if (StringUtil.isNotEmpty(xp)) {
				reqDataJson.put("xp", xp);
			}
		}
		
		if ("1008".equals(busiType)) {
		}
		
		if ("1009".equals(busiType)) {
		}
		
		if ("1010".equals(busiType)) {
		}
		
		if ("1011".equals(busiType)) {
			if (StringUtil.isNotEmpty(ip)) {
				reqDataJson.put("ip", ip);
			}
		}
		
		if ("1012".equals(busiType)) {
			if (StringUtil.isNotEmpty(mchntCode)) {
				reqDataJson.put("mchntCode", mchntCode);
			}
			if (StringUtil.isNotEmpty(mchntCodeTp)) {
				reqDataJson.put("mchntCodeTp", mchntCodeTp);
			}
		}
		
		if ("1013".equals(busiType)) {
			if (StringUtil.isNotEmpty(imei)) {
				reqDataJson.put("imei", imei);
			}
		}
		
		if ("1014".equals(busiType)) {
			if (StringUtil.isNotEmpty(hardDiskSerialNum)) {
				reqDataJson.put("hardDiskSerialNum", hardDiskSerialNum);
			}
		}
		
		if ("1015".equals(busiType)) {
			if (StringUtil.isNotEmpty(webAddr)) {
				reqDataJson.put("webAddr", webAddr);
			}
		}
		
		if ("1016".equals(busiType)) {
		}
		
		if ("1017".equals(busiType)) {
			if (StringUtil.isNotEmpty(sessionId)) {
				reqDataJson.put("sessionId", sessionId);
			}
		}
		
		if ("2001".equals(busiType)) {
			if (StringUtil.isNotEmpty(txnDate)) {
				reqDataJson.put("txnDate", txnDate);
			}
			if (StringUtil.isNotEmpty(queryFlag)) {
				reqDataJson.put("queryFlag", queryFlag);
			}
			if (StringUtil.isNotEmpty(validType)) {
				reqDataJson.put("validType", validType);
			}
		}
		
		if("2002".equals(busiType) || "2003".equals(busiType)){
			if (StringUtil.isNotEmpty(validType)) {
				reqDataJson.put("validType", validType);
			}
		}
		
		if ("2004".equals(busiType)) {
			if (StringUtil.isNotEmpty(sdkMerNo)) {
				reqDataJson.put("sdkMerNo", sdkMerNo);
			}
			if (StringUtil.isNotEmpty(merType)) {
				reqDataJson.put("merType", merType);
			}
			if (StringUtil.isNotEmpty(deviceOs)) {
				reqDataJson.put("deviceOs", deviceOs);
			}
		}
		
		if ("3001".equals(busiType)) {
			if (StringUtil.isNotEmpty(usrName)) {
				reqDataJson.put("usrName", usrName);
			}
			if (StringUtil.isNotEmpty(compareXp)) {
				reqDataJson.put("compareXp", compareXp);
			}
			if (StringUtil.isNotEmpty(deviceOs)) {
				reqDataJson.put("deviceOs", deviceOs);
			}
			if (StringUtil.isNotEmpty(sessionId)) {
				reqDataJson.put("sessionId", sessionId);
			}
		}
		
		if ("3002".equals(busiType)) {
			if (StringUtil.isNotEmpty(usrName)) {
				reqDataJson.put("usrName", usrName);
			}
			if (StringUtil.isNotEmpty(compareXp)) {
				reqDataJson.put("compareXp", compareXp);
			}
			if (StringUtil.isNotEmpty(deviceOs)) {
				reqDataJson.put("deviceOs", deviceOs);
			}
		}
		
		if ("1018".equals(busiType)) {
			if (StringUtil.isNotEmpty(key)) {
				reqDataJson.put("key", key);
			}
			if (StringUtil.isNotEmpty(keyType)) {
				reqDataJson.put("keyType", keyType);
			}
			if (StringUtil.isNotEmpty(orderType)) {
				reqDataJson.put("orderType", orderType);
			}
		}
		
		if ("1020".equals(busiType) || "1022".equals(busiType)) {
			if (StringUtil.isNotEmpty(usrName)) {
				reqDataJson.put("usrName", usrName);
			}
		}
		
		if ("1021".equals(busiType)) {
			if (StringUtil.isNotEmpty(usrName)) {
				reqDataJson.put("usrName", usrName);
			}
		}
		
		if ("1023".equals(busiType)) {
			if (StringUtil.isNotEmpty(usrName)) {
				reqDataJson.put("usrName", usrName);
			}
		}
		
		//敏感域
		Map cardInfoMap = new HashMap();
		if (StringUtil.isNotEmpty(cardNo)) {
			cardInfoMap.put("cardNo", cardNo);
		}
		if (StringUtil.isNotEmpty(certNo)) {
			cardInfoMap.put("certNo", certNo);
		}
		if (StringUtil.isNotEmpty(cardPhone)) {
			cardInfoMap.put("cardPhone", cardPhone);
		}
		if (StringUtil.isNotEmpty(pin)) {
			cardInfoMap.put("pin", pin);
		}
		if (!cardInfoMap.isEmpty()) {
			secssUtil.encryptData(new ObjectMapper().writeValueAsString(cardInfoMap));
		}
		if(!"00".equals(secssUtil.getErrCode())){
			logger.debug("敏感信息加密发生错误，错误信息为"+secssUtil.getErrMsg());
			return;
		}
		reqDataJson.put("sensData", secssUtil.getEncValue());
		
		
		//base64 加密
		if(reqDataJson.size()!=0){
			logger.debug("base64加密前的请求信息=["+reqDataJson.toString()+"]");
			reqDataStr = encodeBase64(reqDataJson.toString().getBytes("UTF-8"));
			logger.debug("base64加密后的请求信息=["+reqDataStr+"]");
		}
		//base64 解密
		//logger.debug("base64解密后=["+new String(Base64.decode(reqDataStr.toCharArray()), "UTF-8")+"]");
		
		} catch (JSONException e1)
		{
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		// 摘要加密SHA512
		String encReqDataStr = Encryptor.encode(reqDataStr, "SHA-512");
		logger.info("摘要加密（SHA-512）encReqDataStr=[" + encReqDataStr + "];");
		Map<String, Object> reqDataMap = new HashMap<String,Object>();
		reqDataMap.put("reqData", encReqDataStr);
		//商户签名
		secssUtil.sign(reqDataMap);
		String signature = secssUtil.getSign();
		logger.debug("signature-->"+signature);
		
		Map<String, Object> sendMap = new HashMap<String,Object>();
		sendMap.put("reqData", reqDataStr);
		sendMap.put("merNo", merNo);
		sendMap.put("signature", signature);
		if (StringUtil.isNotEmpty(instId)) {
			sendMap.put("instId", instId);
	    }
		
		//请求地址
		String vasap_request_url = null;
		if("2001".equals(busiType) || "2002".equals(busiType) || "2003".equals(busiType) || "2004".equals(busiType)){
			vasap_request_url = PathUtil.getValue("result_query_url");
			}
		else{
			vasap_request_url = PathUtil.getValue("bussiness_request_url");
		}
		String sendmsg = getURLParam(sendMap, true, null);
		logger.debug("请求URL:[" + vasap_request_url + "]");
		logger.debug("请求报文信息:[" + sendmsg + "]");
		
		response.getWriter().write(sendmsg);
	}
	
	/** 
	 * 报文解析  .
	 * @author 
	 * @serial  .
	 * @since 2012-10-11 上午09:01:57 .
	 * @param request .
	 * @return Map  .
	 */
	public Map parseParam(HttpServletRequest request) {
		Map paramsMap = new HashMap();
		Enumeration paramsEnum = request.getParameterNames();
		while (paramsEnum.hasMoreElements()) {
			String paramName = (String) paramsEnum.nextElement();
			String paramValue = request.getParameter(paramName);
			paramsMap.put(paramName, paramValue);
		}
		return paramsMap;
	}

	/** 
	 * 转换成url参数  .
	 * @author 
	 * @serial  .
	 * @since 2012-10-11 上午09:01:57 .
	 * @param map .
	 * @param isSort .
	 * @param removeKey .
	 * @return String  .
	 */
	public String getURLParam(Map map, boolean isSort, Set removeKey) {
		StringBuffer param = new StringBuffer();
		List msgList = new ArrayList();
		for (Iterator it = map.keySet().iterator(); it.hasNext();) {
			String key = (String) it.next();
			String value = (String) map.get(key);
			if (removeKey != null && removeKey.contains(key)) {
				continue;
			}
			msgList.add(key + "=" + value);
		}

		if (isSort) {
			// 排序
			Collections.sort(msgList);
		}

		for (int i = 0; i < msgList.size(); i++) {
			String msg = (String) msgList.get(i);
			if (i > 0) {
				param.append("&");
			}
			param.append(msg);
		}

		return param.toString();
	}
	/** 
	 * base64编码  .
	 * @param s .
	 * @return String  .
	 */
	public static String encodeBase64(byte[] s) {
		if (s == null) {
			return null;
		}
		return new String(Base64.encode(s));
	}
	
	/** 
	 * 将url参数转换成map  .
	 * @param param aa=11&bb=22&cc=33 .
	 * @return Map<String, Object>  .
	 */
	public  Map<String, Object> getUrlParams(String param) {  
	    Map<String, Object> map = new HashMap<String, Object>(0);  
	    if (StringUtil.isEmpty(param)) {  
	        return map;  
	    }  
	    String[] params = param.split("&");  
	    for (int i = 0; i < params.length; i++) {  
	        String[] p = params[i].split("=");  
	        if (p.length == 2) {  
	        	if(params[i].endsWith("=")){
		        	map.put(p[0], params[i].substring(p[0].length()+1));  
		        }else{
		        	map.put(p[0], p[1]);  
		        }
	        }  
	    }  
	    return map;  
	}
}
